package com.financial.business.yspay.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.financial.business.yspay.connector.YsBusinessFeign;
import com.financial.business.yspay.connector.YsQueryFeign;
import com.financial.business.yspay.constants.FinancialRefundYsEnumConstants;
import com.financial.business.yspay.dao.FinancialRefundYsDao;
import com.financial.business.yspay.domain.FinancialRefundYsDO;
import com.financial.business.yspay.dto.YsRefundDTO;
import com.financial.business.yspay.dto.refund.YsOrderDivListDTO;
import com.financial.business.yspay.dto.refund.YsRefundSplitInfoDTO;
import com.financial.business.yspay.service.FinancialRefundYsService;
import com.financial.business.yspay.utils.JsonUtils;
import com.financial.business.yspay.utils.ValidateUtils;
import com.financial.business.yspay.utils.apiresult.ApiResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;


@Service
public class FinancialRefundYsServiceImpl implements FinancialRefundYsService {
    public static final Logger logger = LoggerFactory.getLogger(FinancialRefundYsServiceImpl.class);

    @Autowired
    private FinancialRefundYsDao financialRefundYsDao;

    @Autowired
    private YsBusinessFeign ysBusinessFeign;

    @Autowired
    private YsQueryFeign ysQueryFeign;

    @Override
    public FinancialRefundYsDO get(Integer id) {
        return financialRefundYsDao.get(id);
    }

    @Override
    public List<FinancialRefundYsDO> list(Map<String, Object> map) {
        return financialRefundYsDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return financialRefundYsDao.count(map);
    }

    @Override
    public int save(FinancialRefundYsDO financialRefundYs) {
        return financialRefundYsDao.save(financialRefundYs);
    }

    @Override
    public int update(FinancialRefundYsDO financialRefundYs) {
        return financialRefundYsDao.update(financialRefundYs);
    }

    /**
     * 银盛分账退款
     *
     * @param requestParam
     * @return
     */
    @Override
    public ApiResult ysRefund(String requestParam) {
        logger.info("FinancialRefundYsServiceImpl.ysRefund()------监听到平台内部退款完成json为：" + requestParam);
        List storeNoList = new ArrayList();
        YsRefundDTO ysRefundDTO = JsonUtils.convertBean(requestParam, YsRefundDTO.class);
        Map<String, Object> mapParams = JsonUtils.jsonToMap(requestParam);
        Object tempParams = mapParams.get("refund_amount");
        /*分账退款金额*/
        String refundAmountStr = tempParams == null ? null : tempParams.toString();
        /*对接平台主商户号---gyyoudian*/
        tempParams = mapParams.get("src_usercode");
        String srcUsercode = tempParams == null ? null : tempParams.toString();
        /*三方支付专用交易单号*/
        tempParams = mapParams.get("out_trade_no");
        String outTradeNo = tempParams == null ? null : tempParams.toString();
        /*对接平台退款单号*/
        tempParams = mapParams.get("refund_no");
        String refundNo = tempParams == null ? null : tempParams.toString();
        /*提现类型*/
        tempParams = mapParams.get("refund_type");
        String refundType = tempParams == null ? null : tempParams.toString();
        /*对接平台编码*/
        tempParams = mapParams.get("platform_no");
        String platformNo = tempParams == null ? null : tempParams.toString();
        /*商户日期(该参数做交易与查询时需要一致) */
        tempParams = mapParams.get("shopdate");
        String shopdate = tempParams == null ? null : tempParams.toString();
        /*退款原因*/
        tempParams = mapParams.get("refund_reason");
        String refundReason = tempParams == null ? null : tempParams.toString();
        /*标识一次退款请求*/
        tempParams = mapParams.get("out_request_no");
        String outRequestNo = tempParams == null ? null : tempParams.toString();
        /*退款refund_split_info列表*/
        JSONArray refundSplitInfoArray = (JSONArray) mapParams.get("refund_split_info");
        List<YsRefundSplitInfoDTO> refundSplitInfoList = JsonUtils.jsonToList(refundSplitInfoArray.toString(), YsRefundSplitInfoDTO.class);
        for (YsRefundSplitInfoDTO ysRefundSplitInfo : refundSplitInfoList) {
            String refundMerId = ysRefundSplitInfo.getRefund_mer_id();
            String refundAmount = ysRefundSplitInfo.getRefund_amount();
            if (StringUtils.isBlank(refundMerId) || StringUtils.isBlank(refundAmount)) {
                return ApiResult.failure("请检查refund_mer_id或者refund_amount不为空");
            }
            storeNoList.add(refundMerId);
        }
        /*退款order_div_list列表*/
        JSONArray orderDivListArray = (JSONArray) mapParams.get("order_div_list");
        List<YsOrderDivListDTO> orderDivList = JsonUtils.jsonToList(orderDivListArray.toString(), YsOrderDivListDTO.class);
        logger.info("FinancialRefundYsServiceImpl.ysRefund()------获取orderDivList",orderDivList);
        for (YsOrderDivListDTO orderDivListDTO : orderDivList) {
            String divisionMerId = orderDivListDTO.getDivision_mer_id();
            String isChargeFee = orderDivListDTO.getIs_charge_fee();
            if (StringUtils.isBlank(divisionMerId) || StringUtils.isBlank(isChargeFee)) {
                return ApiResult.failure("请检查division_mer_id或者is_charge_fee不为空");
            }
        }
        if (StringUtils.isBlank(refundAmountStr) || StringUtils.isBlank(outTradeNo)
                || StringUtils.isBlank(refundNo) || StringUtils.isBlank(refundType)
                || StringUtils.isBlank(platformNo) || StringUtils.isBlank(refundReason)
                || StringUtils.isBlank(shopdate) || StringUtils.isBlank(outRequestNo)
                || StringUtils.isBlank(srcUsercode)) {
            return ApiResult.failure(ValidateUtils.validateProperty(ysRefundDTO));
        }
        /*分账退款金额精确度保留两位小数*/
        BigDecimal refundAmount = new BigDecimal(refundAmountStr).setScale(2, RoundingMode.HALF_UP);
        ApiResult apiResult = null;
        try {
            /*查询分账状态*/
            ApiResult queryResult = ysQueryFeign.split(requestParam);
            logger.info("FinancialRefundYsServiceImpl.ysRefund()------该笔退款订单分账状态为:" + queryResult);
            String splitQueryReturn = (String) queryResult.getResult();
            Map<String, Object> resultMap = JsonUtils.jsonToMap(splitQueryReturn);
            logger.info("FinancialRefundYsServiceImpl.ysRefund()------退款流程--分账查询结果集" + resultMap.toString());
            String divisionStatusCode = resultMap.get("division_status_code").toString();
            if (!divisionStatusCode.equals("00") && !divisionStatusCode.equals("02")) {
                logger.info("FinancialRefundYsServiceImpl.ysRefund()------该笔退款订单分账状态为失败:");
                return ApiResult.failure("当前分账未成功，请稍后重试！");
            }
            /*保存银盛退款初始化表*/
            FinancialRefundYsDO financialRefundYsDO = new FinancialRefundYsDO();
            /*通过订单号查询库数据*/
            FinancialRefundYsDO financialRefundYsDOInfo=financialRefundYsDao.getOne(outTradeNo);
            logger.info("FinancialRefundYsServiceImpl.ysRefund()------通过订单号查询银盛退款订单信息:订单号为:{}",outTradeNo);
            int res =0;
            if(financialRefundYsDOInfo!=null){
                logger.info("FinancialRefundYsServiceImpl.ysRefund()------通过订单号查询银盛退款订单信息存在，执行更新操作");
                BigDecimal totalAmountData=financialRefundYsDOInfo.getTotalAmount();
                Map<String,Object> dataParams=new HashMap<>();
                dataParams.put("outTradeNo",outTradeNo);
                dataParams.put("gmtModified",new Date());
                dataParams.put("returnMessage",FinancialRefundYsEnumConstants.ENUM_REFUND_INIT);
                dataParams.put("state",FinancialRefundYsEnumConstants.ENUM_STATE_WAIT);
                logger.info("FinancialRefundYsServiceImpl.ysRefund()------通过订单号查询银盛退款订单信息:订单号为:{}退款金额为:{}",outTradeNo,totalAmountData);
                String state=financialRefundYsDOInfo.getState();
                logger.info("FinancialRefundYsServiceImpl.ysRefund()------通过订单号查询银盛退款订单信息:订单号为:{},订单状态为:{}",outTradeNo,state);
                if(totalAmountData.compareTo(refundAmount)!=0){
                    logger.info("FinancialRefundYsServiceImpl.ysRefund()------历史订单退款金额与当前退款金额不符");
                    return ApiResult.failure("订单退款金额不符!");
                }
                if(state.equals("1")){
                    logger.info("FinancialRefundYsServiceImpl.ysRefund()------历史订单退款状态为1，退款成功!");
                    return ApiResult.success("订单退款成功");
                }else{
                    logger.info("FinancialRefundYsServiceImpl.ysRefund()------历史订单退款状态退款不成功或为发起退款");
                    res=financialRefundYsDao.updateInfo(dataParams);
                }
            }else{
                logger.info("FinancialRefundYsServiceImpl.ysRefund()------通过订单号查询银盛退款订单信息存在，执行创建操作");
                financialRefundYsDO.setGmtCreate(new Date());
                financialRefundYsDO.setIsDelete(FinancialRefundYsEnumConstants.ENUM_ISDELETE_UNDEL);
                financialRefundYsDO.setOutTradeNo(outTradeNo);
                financialRefundYsDO.setPlatformNo(platformNo);
                financialRefundYsDO.setRefundNo(refundNo);
                financialRefundYsDO.setState(FinancialRefundYsEnumConstants.ENUM_STATE_WAIT);
                financialRefundYsDO.setStoreNo(JsonUtils.toJSon(storeNoList.toString()));
                financialRefundYsDO.setTotalAmount(refundAmount);
                financialRefundYsDO.setResqContent(requestParam);
                financialRefundYsDO.setReturnMessage(FinancialRefundYsEnumConstants.ENUM_REFUND_INIT);
                res = financialRefundYsDao.save(financialRefundYsDO);
            }
            if (res > 0) {
                /*请求银盛分账*/
                apiResult = ysBusinessFeign.refund(requestParam);
                logger.info("FinancialRefundYsServiceImpl.ysRefund()------请求银盛退款返回json为:" + apiResult);
                /*根据返回信息进行状态判断*/
                Integer code = apiResult.getCode();
                String resultMsg = apiResult.getResult().toString();
                Map<String, Object> condMap = new HashMap<>();
                condMap.put("outTradeNo", outTradeNo);
                condMap.put("returnMessage", resultMsg);
                if (code == FinancialRefundYsEnumConstants.ENUM_RETURN_CODE && (resultMsg != null && resultMsg != "")) {
                    /*成功状态*/
                    condMap.put("state", FinancialRefundYsEnumConstants.ENUM_STATE_SUC);
                    int updateInfoState = financialRefundYsDao.updateInfo(condMap);
                    if (updateInfoState > 0) {
                        logger.info("FinancialRefundYsServiceImpl.ysRefund()------调用银盛退款返回数据为成功，退款更改数据库状态成功");
                        return ApiResult.success(resultMsg);
                    } else {
                        return ApiResult.failure(apiResult);
                    }
                } else {
                    condMap.put("state", FinancialRefundYsEnumConstants.ENUM_STATE_FAIL);
                    financialRefundYsDao.updateInfo(condMap);
                    logger.info("FinancialRefundYsServiceImpl.ysRefund()------调用银盛退款返回数据为失败，退款更改数据库状态失败--成功");
                    return ApiResult.failure(apiResult);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return apiResult;
    }

    /**
     * 通过map查询一条退款记录
     *
     * @param condMap
     * @return
     */
    @Override
    public String query(Map<String, Object> condMap) {

        return financialRefundYsDao.query(condMap);
    }

}
